# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.contrib import admin
from django.apps import apps
from django.http import Http404
from django.utils.encoding import smart_text
from django.utils.text import capfirst
from django.core.paginator import InvalidPage, Paginator
from django.urls import reverse, NoReverseMatch
import xadmin
from haystack.forms import model_choices
from haystack.query import EmptySearchQuerySet, SearchQuerySet
from haystack.views import SearchView
from haystack.utils.app_loading import haystack_get_model
from haystack.utils import get_model_ct
from haystack import connections
from haystack.constants import DEFAULT_ALIAS


# Register your models here.


class SearchMixin(object):
    title = u"搜索"
    template_name = 'xadmin/search.html'
    searchqueryset = SearchQuerySet()
    load_all = True
    q = ""
    app_name = None
    model_name = None
    results_per_page = 20

    def get_search_context(self):
        self.q = request.GET.get('q', "")
        self.app_name = request.GET.get('app', None)
        self.model_name = request.GET.get('model', None)

        (apps, models) = self.get_app_index_models(self.app_name)
        self.results = self.get_results()
        (paginator, page) = self.build_page()

        new_context = {
            'title': self.title,
            "models": models,
            "apps": apps,
            'query': self.q,
            "app_name": self.app_name,
            "model_name": self.model_name,
            'page': page,
            'paginator': paginator,
            'suggestion': None,
        }
        if hasattr(self.results, 'query') and self.results.query.backend.include_spelling:
            new_context['suggestion'] = self.get_suggestion()
        return new_context

    def get_app_index_models(self, app_label):
        using = DEFAULT_ALIAS
        all_models = [(get_model_ct(m), capfirst(smart_text(m._meta.verbose_name_plural)))
                      for m in connections[using].get_unified_index().get_indexed_models()]

        _apps = {}
        for (m, v) in all_models:
            (app_name, model_name) = m.split(".")
            if _apps.has_key(app_name):
                continue
            conf = apps.get_app_config(app_name)
            admin_url = None
            try:
                admin_url = reverse("xadmin:%s_index" % app_name)
            except:
                pass
            _apps[app_name] = {
                'app_name': app_name,
                "verbose_name": conf.verbose_name,
                'admin_url': admin_url
            }
        if not app_label:
            return (_apps.values(), None)
        app_models = [{'name': m, 'label': v} for (m, v) in all_models if m.startswith(app_label)]
        return (_apps.values(), app_models)

    def no_query_found(self):
        return EmptySearchQuerySet()

    def get_results(self):
        if not self.q:
            return self.no_query_found()
        sqs = self.searchqueryset.auto_query(self.q)
        if self.load_all:
            sqs = sqs.load_all()
        if self.model_name:
            (app_label, model) = self.model_name.split(".")
            _model_cls = haystack_get_model(app_label, model)
            sqs = sqs.models(_model_cls)
        return sqs

    def build_page(self):
        try:
            page_no = int(self.request.GET.get('page', 1))
        except (TypeError, ValueError):
            raise Http404("分页错误！")
        if page_no < 1:
            raise Http404("分页至少从1页开始!")
        start_offset = (page_no - 1) * self.results_per_page
        self.results[start_offset:start_offset + self.results_per_page]
        paginator = Paginator(self.results, self.results_per_page)
        try:
            page = paginator.page(page_no)
        except InvalidPage:
            raise Http404("不存在第%s页信息!" % page_no)
        return (paginator, page)

    def get_suggestion(self):
        if not self.q:
            return None

        return self.searchqueryset.spelling_suggestion(self.q)
